home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
C
/
LIB
/
UNIXLIB37B
/
!UnixLib37
/
src
/
stdio
/
c
/
popen
< prev
next >
Wrap
Text File
|
1996-11-09
|
3KB
|
179 lines
/****************************************************************************
*
* $Source: /unixb/home/unixlib/source/unixlib37/src/stdio/c/RCS/popen,v $
* $Date: 1996/10/30 21:59:00 $
* $Revision: 1.3 $
* $State: Rel $
* $Author: unixlib $
*
* $Log: popen,v $
* Revision 1.3 1996/10/30 21:59:00 unixlib
* Massive changes made by Nick Burret and Peter Burwood.
*
* Revision 1.2 1996/05/06 09:01:34 unixlib
* Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
* Saved for 3.7a release.
*
* Revision 1.1 1996/04/19 21:32:42 simon
* Initial revision
*
***************************************************************************/
static const char rcs_id[] = "$Id: popen,v 1.3 1996/10/30 21:59:00 unixlib Rel $";
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/wait.h>
__STDIOLIB__
struct pwr
{
FILE *f;
int p0;
char *command;
struct pwr *next;
};
static struct pwr *__pwr = 0;
static void
__pexec (const char *command)
{
char *shell, *path;
if (!(path = getenv ("SHELL")))
if (execl (command, "", 0))
_exit (1);
shell = strrchr (path, '/');
if (shell)
shell++;
else
shell = path;
if (execl (path, shell, "-c", (char *) command, 0))
_exit (1);
}
FILE *
popen (const char *command, const char *mode)
{
FILE *f;
int p[2];
if (pipe (p) < 0)
return (0);
if (*mode == 'r')
switch (fork ())
{
case -1:
close (p[0]);
close (p[1]);
return (0);
break;
case 0:
close (p[0]);
dup2 (p[1], 1);
close (p[1]);
__pexec (command);
break;
default:
close (p[1]);
if (!(f = fdopen (p[0], mode)))
return (0);
f->flag |= _IOPIPE;
return (f);
break;
}
else
{
FILE *f;
struct pwr *pwr;
if (!(pwr = malloc (sizeof (struct pwr))))
return (0);
if (!(pwr->command = strdup (command)))
{
free (pwr);
return (0);
}
if (!(f = fdopen (p[1], mode)))
{
free (pwr);
free (pwr->command);
return (0);
}
f->flag |= _IOPIPE;
pwr->f = f;
pwr->p0 = p[0];
pwr->next = __pwr;
__pwr = pwr;
return (f);
}
/* never reached */
return (0);
}
int
pclose (FILE * f)
{
int r;
if (!fispipe (f))
return (-1);
if ((f->flag & _IOOMASK) == _IOWRITE)
{
struct pwr *pwr = __pwr, *pwr_ = 0;
while (pwr)
{
if (pwr->f == f)
break;
pwr_ = pwr;
pwr = pwr->next;
}
if (!pwr)
return (-1);
if (pwr_)
pwr_->next = pwr->next;
else
__pwr = pwr->next;
fflush (f);
switch (fork ())
{
case -1:
close (pwr->p0);
close (f->fd);
return (-1);
break;
case 0:
close (f->fd);
dup2 (pwr->p0, 0);
close (pwr->p0);
__pexec (pwr->command);
break;
default:
close (pwr->p0);
break;
}
free (pwr->command);
free (pwr);
}
r = (wait (0) >> 8);
if (fclose (f))
return (-1);
return (r);
}